package com.zhidian.edm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zhidian.edm.entity.*;
import com.zhidian.edm.exception.BusinessException;
import com.zhidian.edm.mapper.*;
import jakarta.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    private SysUserMapper userRepository;
    @Resource
    private SysUserRoleMapper userRoleRepository;
    @Resource
    private SysRoleMapper roleRepository;
    @Resource
    private SysRoleMenuMapper roleMenuRepository;
    @Resource
    private SysMenuMapper menuRepository;



    public UserDetails loadUserById(Long userId) {
        // 1. 查询用户信息
        SysUserPO user = Optional.ofNullable(userRepository.selectById(userId))
                .orElseThrow(() -> new BusinessException("用户不存在"));

        // 2. 查询用户角色
        List<SysUserRolePO> userRoles = userRoleRepository.selectList(
                new LambdaQueryWrapper<SysUserRolePO>().eq(SysUserRolePO::getUserId, userId)
        );

        List<Long> roleIds = userRoles.stream()
                .map(SysUserRolePO::getRoleId)
                .toList();

        List<SysRolePO> roles = roleIds.isEmpty()
                ? Collections.emptyList()
                : roleRepository.selectByIds(roleIds);

        // 3. 查询角色对应的菜单权限
        List<SysMenuPO> menus = Collections.emptyList();
        if (!roleIds.isEmpty()) {
            List<SysRoleMenuPO> roleMenus = roleMenuRepository.selectList(
                    new LambdaQueryWrapper<SysRoleMenuPO>().in(SysRoleMenuPO::getRoleId, roleIds)
            );
            List<Long> menuIds = roleMenus.stream()
                    .map(SysRoleMenuPO::getMenuId)
                    .toList();
            if (!menuIds.isEmpty()) {
                menus = menuRepository.selectByIds(menuIds);
            }
        }

        // 4. 构建权限集合
        List<GrantedAuthority> authorities = new ArrayList<>();

        // 菜单权限
        menus.stream()
                .map(SysMenuPO::getPermission)
                .filter(StringUtils::hasText)
                .forEach(p -> authorities.add(new SimpleGrantedAuthority(p)));

        // 角色权限
        roles.stream()
                .map(SysRolePO::getCode)
                .filter(StringUtils::hasText)
                .map(code -> code.startsWith("ROLE_") ? code : "ROLE_" + code.toUpperCase())
                .forEach(roleCode -> authorities.add(new SimpleGrantedAuthority(roleCode)));

        // 如果没有角色和权限，给一个默认角色
        if (authorities.isEmpty()) {
            authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        }

        return new org.springframework.security.core.userdetails.User(
                user.getUserName(),
                user.getPassword(),
                authorities
        );
    }


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUserPO user = Optional.ofNullable(userRepository.selectOne(new LambdaQueryWrapper<SysUserPO>().eq(SysUserPO::getUserName, username))).orElseThrow(() -> new UsernameNotFoundException("用户不存在"));
        return loadUserById(user.getId());
    }
}